/** @file    posix/pthread_thread.cpp
 *  @author  Alessandro Polo
 *  @version $Id: pthread_thread.cpp 2628 2010-06-08 23:30:40Z alex $
 *  @brief   
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

 #include <core/posix/pthread_thread.h>

 #include <stdio.h> //@bug BUG: TEMP TO BE REMOVED


/*

*/

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void* ThreadImpl_PThread_runner_helper( void* ptr ) {
	ThreadImpl_PThread* thread = reinterpret_cast<ThreadImpl_PThread*>(ptr);
	if ( thread == NULL ) return NULL;
	thread->run();
	return NULL;
 }


ThreadImpl_PThread::ThreadImpl_PThread( const wosh::Object* owner, const std::string& threadName )
	: wosh::Thread(owner, threadName), p_thread(NULL) {
	// changes the thread affinity for this object and its children
	
	setThreadState( wosh::Thread::STATE_CREATED );
 }

ThreadImpl_PThread::~ThreadImpl_PThread() {
	setThreadState( wosh::Thread::STATE_DESTROYED );
 }

WRESULT ThreadImpl_PThread::startThread( unsigned long synch_timeout ) {
	int iret1 = pthread_create( &this->p_thread, NULL, ThreadImpl_PThread_runner_helper, (void*)this );
	if ( synch_timeout == 1 ) {
		printf("\nWRESULT Thread::startThread( 1 ) [%s]\n", getThreadName().c_str() );
	}
	bool started = wosh::Thread::waitState( this, wosh::Thread::STATE_RUNNING, synch_timeout );
	if ( started )
		return WRET_OK;
	// probably the initializeThread() returned false! or waiting timed out..
	// let' the thread exit RUN call
	// else we may edit/destroy thread while still running
	// this is because initializeThread() is inside RUN()!
//	if ( getThreadState() == STATE_FAILURE )
//		QThread::wait();
	if ( synch_timeout == 0 ) // was asynch
		return WRET_OK;
	return WRET_ERR_INTERNAL;
 }

WRESULT ThreadImpl_PThread::quitThread( unsigned long synch_timeout ) {
	this->running = false; // stop implemented loop if any
//	QThread::quit();
	if ( synch_timeout == 1 ) {
		printf("\nWRESULT Thread::quitThread( 1 ) [%s]\n", getThreadName().c_str() );
	}
	bool stopped = wosh::Thread::waitState( this, wosh::Thread::STATE_STOPPED, synch_timeout );
	if ( stopped || synch_timeout == 0 )
		return WRET_OK;
	return WRET_ERR_INTERNAL;
 }

bool ThreadImpl_PThread::waitThread( unsigned long time ) {
//	return QThread::wait(time);
	pthread_join( this->p_thread, NULL);
	return false;
}

void ThreadImpl_PThread::terminateThread() {
//	QThread::terminate();
 }

bool ThreadImpl_PThread::isThreadRunningInternal() const {
//	return QThread::isRunning();
	return false;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ThreadImpl_PThread::run() {
//	setThreadID( (long)QThread::currentThreadId() );
	bool initialized = initializingThread();
	if ( !initialized ) {
		this->running = false;
		setThreadState( Thread::STATE_FAILURE );
		return;
	 }
	setThreadState( wosh::Thread::STATE_RUNNING );
	this->running = true;
	runThread();
	this->running = false;
	exitingThread();
	setThreadState( wosh::Thread::STATE_STOPPED );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
